package com.demo.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.demo.constant.Constant;
import com.demo.entity.Department;
import com.demo.entity.User;
import com.demo.enums.PreventiveDoctorAdviceStatusEnum;
import com.demo.mapper.*;
import com.demo.response.Result;
import com.demo.service.IDepartmentService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 医院科室信息表 服务实现类
 *
 * @author zm
 * @since 2020-11-26
 */
@Service
@Slf4j
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements IDepartmentService {
    @Resource
    DepartmentMapper departmentMapper;
    @Resource
    PatientMapper patientMapper;
    @Resource
    VtePreventiveMapper vtePreventiveMapper;
    @Resource
    DvtDiagnoseMapper dvtDiagnoseMapper;
    @Resource
    VtePreventiveDoctorAdviceMapper doctorAdviceMapper;
    @Resource
    UserMapper userMapper;

    /**
     * 新增医院科室信息
     *
     * @param department 实体对象
     * @return
     */
    @Override
    public Result addDepartment(Department department) throws Exception {
        //病区编号与病区映射唯一
        Department deparSn = departmentMapper.getdeptSn(department.getDeptSn());
        if (deparSn != null) {
            throw new Exception("病区编号已存在");
        }
        Department deparMapping = departmentMapper.getdeptMapping(department.getDeptMapping());
        if (deparMapping != null) {
            throw new Exception("病区映射已存在");
        }
        Department deparName = departmentMapper.getDeptByName(department.getDeptAreaName());
        if (deparName != null) {
            throw new Exception("病区名称已存在");
        }
        boolean flag = save(department);
        if (flag == false) {
            return Result.error(Constant.DB_ERROR);
        }
        return Result.success();
    }

    /**
     * 更新医院科室信息
     *
     * @param department 实体对象
     * @return
     */
    @Override
    public Result updateDepartment(Department department) throws Exception {
        if (department.getDeptNo() == null || department.getUpdatedUserId() == null) {
            return Result.error(Constant.KEY_ID);
        }
        //病区编号与病区映射唯一
        if (department.getDeptSn() != null) {
            Department deparSn = departmentMapper.getdeptSn(department.getDeptSn());
            if (deparSn != null) {
                if (!deparSn.getDeptNo().equals(department.getDeptNo())) {
                    throw new Exception("病区编号已存在");
                }
            }
        }
        if (department.getDeptMapping() != null) {
            Department deparMapping = departmentMapper.getdeptMapping(department.getDeptMapping());
            if (deparMapping != null) {
                if (!deparMapping.getDeptNo().equals(department.getDeptNo())) {
                    throw new Exception("病区映射已存在");
                }
            }
        }

        boolean flag = updateById(department);
        if (flag == false) {
            return Result.error(Constant.DB_ERROR);
        }
        return Result.success();
    }

    /**
     * 删除医院科室信息
     *
     * @param deptNo        部门科室编号
     * @param deletedUserId 删除人ID
     * @return
     */
    @Override
    public Result deleteDepartment(Integer deptNo, Integer deletedUserId) {
        Department department = new Department();
        department.setDeptNo(deptNo);
        department.setDeletedUserId(deletedUserId);
        department.setDeletedTime(new Date());
        boolean flag = updateById(department);
        if (flag == false) {
            return Result.error(Constant.DB_ERROR);
        }
        return Result.success();
    }

    /**
     * 医院科室信息列表
     *
     * @param pageNumber 页码
     * @param pageSize   大小
     * @param deptType   类型1内科2外科
     * @return
     */
    @Override
    public Result departmentList(Integer pageNumber, Integer pageSize, Integer deptType) {
        IPage<Department> page = new Page<>(pageNumber, pageSize);
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(deptType != null, "dept_type", deptType);
        queryWrapper.isNull("deleted_user_id");
        queryWrapper.orderByDesc("dept_no");
        page = departmentMapper.selectPage(page, queryWrapper);
        PageInfo<Department> pageInfo = new PageInfo<>(page.getRecords());
        pageInfo.setTotal(page.getTotal());
        pageInfo.setPages((int) page.getPages());
        if (pageNumber.equals(page.getPages())) {
            pageInfo.setIsLastPage(false);
        } else {
            pageInfo.setIsLastPage(true);
        }
        return Result.success(pageInfo);
    }

    /**
     * 用户所在医院科室信息列表
     *
     * @param pageNumber 页码
     * @param pageSize   大小
     * @param userId     类型1内科2外科
     * @return
     */
    @Override
    public Result userDepartmentList(Integer pageNumber, Integer pageSize, Integer userId) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        User user = userMapper.selectOne(queryWrapper);
        String userDepartList = user.getUserDepartment();
        List<Department> departmentsList = new ArrayList<>();
        if (!userDepartList.isEmpty()) {
            for (String item : userDepartList.split(",")) {
                Department department = departmentMapper.getdeptNoList(Integer.parseInt(item));
                if (department != null) {
                    departmentsList.add(department);
                }
            }
        }
        IPage<Department> page = new Page<>(pageNumber, pageSize);
        PageInfo<Department> pageInfo = new PageInfo<>(departmentsList);
        pageInfo.setTotal(departmentsList.size());
        pageInfo.setPages((int) page.getPages());
        if (pageNumber.equals(page.getPages())) {
            pageInfo.setIsLastPage(false);
        } else {
            pageInfo.setIsLastPage(true);
        }
        return Result.success(pageInfo);
    }

    /**
     * 科室VTE患者防治监控
     *
     * @return
     */
    @Override
    public Result departmentMonitor(Integer deptSn) {
        Integer hospitalizedSum = patientMapper.getHospitalizedSum(deptSn);
        Integer[] noRank = new Integer[0];
        Integer vtePreventiveSum = vtePreventiveMapper.getVteSumByDeptSn(deptSn, noRank);
        Integer vteDvtSum = dvtDiagnoseMapper.getDvtSumByDeptSn(deptSn);
        Integer vtePhysicalSum = doctorAdviceMapper.getDoctorAdviceSumByDeptSn(deptSn, PreventiveDoctorAdviceStatusEnum.HAS_STOP.getValue(), "onlyPhysical");
        Integer vteMedicineSum = doctorAdviceMapper.getDoctorAdviceSumByDeptSn(deptSn, PreventiveDoctorAdviceStatusEnum.UN_STOP.getValue(), "onlyMedicine");
        Integer vteDoctorAdviceSum = doctorAdviceMapper.getDoctorAdviceSumByDeptSn(deptSn, null, "or");
        Integer vteDoctoPhysicalSum = doctorAdviceMapper.getDoctorAdviceSumByDeptSn(deptSn, null, "and");
        Map<String, String> report = new HashMap<>();
        Integer[] lowRank = {1};
        Integer[] middleRank = {3};
        Integer[] highRank = {2};
        Integer vteLowSum = vtePreventiveMapper.getVteSumByDeptSn(deptSn, lowRank);
        Integer vteMiddleSum = vtePreventiveMapper.getVteSumByDeptSn(deptSn, middleRank);
        Integer vteHighSum = vtePreventiveMapper.getVteSumByDeptSn(deptSn, highRank);
        report.put("hospitalizedSum", Convert.toStr(hospitalizedSum));
        report.put("vtePreventiveSum", Convert.toStr(vtePreventiveSum));
        report.put("vteDvtSum", Convert.toStr(vteDvtSum));
        report.put("vtePhysicalSum", Convert.toStr(vtePhysicalSum));
        report.put("vteMedicineSum", Convert.toStr(vteMedicineSum));
        report.put("vteDoctorAdviceSum", Convert.toStr(vteDoctorAdviceSum));
        report.put("vteDoctoPhysicalSum", Convert.toStr(vteDoctoPhysicalSum));
        report.put("vteLowSum", Convert.toStr(vteLowSum));
        report.put("vteMiddleSum", Convert.toStr(vteMiddleSum));
        report.put("vteHighSum", Convert.toStr(vteHighSum));
        return Result.success(report);
    }

}
